package com.player.rest.util;

import java.util.List;
import java.util.Set;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.player.entity.Game;
import com.player.entity.GameResult;
import com.player.entity.Player;
import com.player.entity.Ranking;
import com.player.entity.RankinglistType;
import com.player.rest.exception.FaultInfo;
import com.player.rest.resource.PlayerResource;
import com.player.util.PlayerDateFormatter;

public class ResponseConverter {

	public static String toJSONPlayer(List<Player> players) throws JSONException {
		JSONObject json = new JSONObject();
		JSONArray jsonPlayers = new JSONArray();
		for (Player player : players) {
			jsonPlayers.put(toJSONPlayer(player));
		}
		json.put("players", jsonPlayers);
		return json.toString();
	}

	public static JSONObject toJSONPlayer(Player player) throws JSONException {
		JSONObject jsonPlayer = new JSONObject();
		jsonPlayer.put("id", player.getId());
		jsonPlayer.put("playername", player.getPlayername());
		jsonPlayer.put("email", player.getEmail());
		jsonPlayer.put("name", player.getName());
		jsonPlayer.put("prename", player.getPrename());
		return jsonPlayer;
	}

	public static JSONArray toJSONArray(Set<String> set) {
		JSONArray jsonArray = new JSONArray();
		if (set != null) {
			for (String message : set) {
				jsonArray.put(message);
			}
		}
		return jsonArray;
	}

	public static String toJSONRanking(List<Ranking> rankings, RankinglistType rankinglist) throws JSONException {
		JSONObject json = new JSONObject();
		json.put("rankings", toJSONRanking(rankings));
		json.put("rankinglist", rankinglist.name());
		return json.toString();
	}

	private static JSONArray toJSONRanking(List<Ranking> rankings) throws JSONException {
		JSONArray jsonRankings = new JSONArray();
		for (Ranking ranking : rankings) {
			JSONObject jsonRanking = new JSONObject();
			jsonRanking.put("id", ranking.getId());

			JSONObject jsonPlayer = new JSONObject();
			jsonPlayer.put("id", ranking.getPlayer().getId());
			jsonPlayer.put("nickname", ranking.getPlayer().getPlayername());
			jsonRanking.put("player", jsonPlayer);

			jsonRanking.put("points", ranking.getPoints());
			jsonRanking.put("trend", ranking.getRankingTrend());
			jsonRanking.put("rank", ranking.getRank());
			jsonRankings.put(jsonRanking);
		}
		return jsonRankings;
	}

	public static JSONObject toJSONGame(Game game) throws JSONException {
		JSONObject jsonGame = new JSONObject();
		jsonGame.put("id", game.getId());
		jsonGame.put("creatorId", game.getCreatorId());
		jsonGame.put("opponentId", game.getOpponentId());
		jsonGame.put("dateCreated", PlayerDateFormatter.dateToString(game.getDateCreated()));
		if (game.hasResult()) {
			GameResult result = game.getResult();
			jsonGame.put("setWonByCreator", result.getSetsWonByCreator());
			jsonGame.put("setWonByOpponent", result.getSetsWonByOpponent());
			jsonGame.put("dateResultCreated", PlayerDateFormatter.dateToString(result.getDateResultCreated()));
			if (result.isConfirmedByOpponent()) {
				jsonGame.put("dateConfirmedByOpponent", PlayerDateFormatter.dateToString(result
						.getDateConfirmedByOpponent()));
			} else {
				jsonGame.put("dateConfirmedByOpponent", "-");
			}
		}
		return jsonGame;
	}

	public static String toJSONGame(List<Game> games) throws JSONException {
		JSONObject json = new JSONObject();
		JSONArray jsonGames = new JSONArray();
		for (Game game : games) {
			jsonGames.put(toJSONGame(game));
		}
		json.put("games", jsonGames);
		return json.toString();
	}

	public static String toJSON(FaultInfo faultInfo) {
		JSONObject json = new JSONObject();
		try {
			JSONObject jsonFaultInfo = new JSONObject();
			jsonFaultInfo.put("errorCode", faultInfo.getErrorCode());
			jsonFaultInfo.put("reason", faultInfo.getReason());
			jsonFaultInfo.put("resource", faultInfo.getResource());
			jsonFaultInfo.put("exception", faultInfo.getException());
			json.put("error", jsonFaultInfo);
		} catch (JSONException e) {
			throw new RuntimeException("Error while creating JSON response for FaultInfo: " + faultInfo);
		}
		return json.toString();
	}

	public static String buildErrorJSON(ValidationResult result) throws JSONException {
		JSONObject json = new JSONObject();
		JSONObject jsonMessageKeys = new JSONObject();
		jsonMessageKeys.put("error", toJSONArray(result.getMessagesForKey("error")));
		jsonMessageKeys.put("email", toJSONArray(result.getMessagesForKey(PlayerResource.FORM_PARAM_EMAIL)));
		jsonMessageKeys.put("playername", toJSONArray(result.getMessagesForKey(PlayerResource.FORM_PARAM_PLAYERNAME)));
		jsonMessageKeys
				.put("rankinglist", toJSONArray(result.getMessagesForKey(PlayerResource.FORM_PARAM_RANKINGLIST)));
		json.put("errors", jsonMessageKeys);

		// Generic Impl (didnt know how to access the json structure in JS)
		// JSONArray jsonMessages = new JSONArray();
		// Map<String, Set<String>> messages = result.getMessages();
		// Set<String> keys = messages.keySet();
		// for (String messageKey : keys) {
		// Set<String> set = messages.get(messageKey);
		// JSONArray jsonMessagesForKey = new JSONArray();
		// for (String message : set) {
		// jsonMessagesForKey.put(message);
		// }
		// JSONObject jsonMessageForKey = new JSONObject();
		// jsonMessageForKey.put(messageKey, jsonMessagesForKey);
		// jsonMessages.put(jsonMessageForKey);
		// }
		// json.put("errors", jsonMessages);

		return json.toString();
	}

}
